﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PingPongGame
{

    public class Manager
    {
        IDrawer drawer;
        IUserInterface userInterface;
        List<GameObject> allObjects;
        List<MovingObject> movingObjects;
        List<GameObject> staticObjects;
        UserRacket playerRacket;
        int sleep;

        public Manager(IDrawer drawer, IUserInterface userInterface)
        {
            this.drawer = drawer;
            this.userInterface = userInterface;
            this.allObjects = new List<GameObject>();
            this.movingObjects = new List<MovingObject>();
            this.staticObjects = new List<GameObject>();
            this.sleep = 500;
        }
        public Manager(IDrawer drawer, IUserInterface userInterface,int sleep):this(drawer, userInterface)
        {
           
            this.sleep = sleep;
        }

        private void AddStaticObject(GameObject obj)
        {
            this.staticObjects.Add(obj);
            this.allObjects.Add(obj);
        }

        private void AddMovingObject(MovingObject obj)
        {
            this.movingObjects.Add(obj);
            this.allObjects.Add(obj);
        }
        

        public virtual void AddObject(GameObject obj)
        {
            if( obj is MovingObject)
            {
                this.AddMovingObject(obj as MovingObject);
            }
            else
            {
                if (obj is UserRacket)
                {
                    AddRacket(obj);

                }
                else
                {
                    this.AddStaticObject(obj);
                }
            }
        }

        private void AddRacket(GameObject  obj)
        {
            //TODO: we should remove the previous racket from this.allObjects
            this.staticObjects.Remove(this.playerRacket);
            this.playerRacket = obj as UserRacket;
            this.AddStaticObject(obj);
        }

        public virtual void MovePlayerRacketUp()
        {
            this.playerRacket.MoveUp();
        }

        public virtual void MovePlayerRacketDown()
        {
            this.playerRacket.MoveDown();
        }
        public virtual void MovePlayerRacketFront()
        {
            this.playerRacket.MoveFront();
        }
        public virtual void MovePlayerRacketBack()
        {
            this.playerRacket.MoveBack();
        }
        public virtual void ReversePlayerRacket()
        {
            this.playerRacket.GetRacketBodyReverce();
        }

        public virtual void Run()
        {
            while (true)
            {
                this.drawer.RenderAll();

                System.Threading.Thread.Sleep(this.sleep);

                this.userInterface.ProcessInput();

                this.drawer.ClearQueue();

                foreach (var obj in this.allObjects)
                {
                    obj.Update();
                    this.drawer.EnqueueForRendering(obj);
                }

                CollisionDispatcher.HandleCollisions(this.movingObjects, this.staticObjects);
                

                List<GameObject> producedObjects = new List<GameObject>();

                foreach (var obj in this.allObjects)
                {
                    producedObjects.AddRange(obj.ProduceObjects());
                }

                this.allObjects.RemoveAll(obj => obj.IsDestroyed);
                this.movingObjects.RemoveAll(obj => obj.IsDestroyed);
                List<GameObject> distroyed=this.staticObjects.FindAll(obj => obj.IsDestroyed);
               
                this.staticObjects.RemoveAll(obj => obj.IsDestroyed);

                foreach (var obj in producedObjects)
                {
                    this.AddObject(obj);
                }
            }
        }
    }
}

